package bean.managed;

import entity.SalesForecastEntity;
import bean.managed.util.JsfUtil;
import bean.managed.util.PaginationHelper;
import bean.session.SalesForecastEntityFacade;

import entity.DepartmentEntity;
import entity.ExpectedYearOnYearGrowthEntity;
import entity.MarketSalesReportEntity;
import entity.MasterProductionScheduleMonthlyEntity;
import entity.ProductPercentageQuantityEntity;
import entity.SystemUserEntity;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.ResourceBundle;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.SessionScoped;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;
import javax.faces.model.DataModel;
import javax.faces.model.ListDataModel;
import javax.faces.model.SelectItem;
import org.primefaces.component.chart.series.ChartSeries;
import org.primefaces.model.chart.CartesianChartModel;
import org.primefaces.model.chart.PieChartModel; 
import type.Month;
import util.Fixtures.Department;

@ManagedBean(name = "salesForecastEntityController")
@SessionScoped
public class SalesForecastEntityController implements Serializable {

    private SalesForecastEntity current=null;
    private DataModel items = null;
    
    @ManagedProperty(value = "#{systemMessageController}")
    private SystemMessageController systemMessageController;
    
    @EJB
    private bean.session.SalesForecastEntityFacade ejbFacade;
    @EJB
    private bean.session.MasterProductionScheduleMonthlyEntityFacade monthlyFacade;
    private PaginationHelper pagination;
    private int selectedItemIndex;
    
    private SalesForecastEntity salesForecast;
    
    private double monthlyAdustBeforeUpdate;
    private long promotionBeforeUpdate;
    private PieChartModel pieModel;
    
    private CartesianChartModel monthlyTrends;;
   
    @EJB
    private bean.session.ExpectedYearOnYearGrowthEntityFacade yoyFacade;
    
    private ExpectedYearOnYearGrowthEntityController yoyController;
    
    @EJB private bean.session.DepartmentEntityFacade departmentFacade;

    public SalesForecastEntityController() {
        
    }
     public CartesianChartModel getMonthlyTrends(){
        monthlyTrends = new CartesianChartModel();
        
        
        int year = current.getYearOfSales();
        Month month = current.getMonthOfSales();
       
        ArrayList<SalesForecastEntity> forecastReport = getFacade().findShortTermSalesForecast(year,month);
        ArrayList<MarketSalesReportEntity> actualTotalSales = getFacade().findActualTotalSales(year,month);
        
        ChartSeries actual = new ChartSeries();  
        actual.setLabel("Acutal Sales Figures");  
        for(MarketSalesReportEntity r:actualTotalSales){
            actual.set(Integer.toString(r.getYear())+" "+r.getMonth(), r.getSalesValue());
        }
          
  
        ChartSeries forecast = new ChartSeries();  
        forecast.setLabel("Forecast Sales Figures");
         for(SalesForecastEntity k:forecastReport){
            forecast.set(Integer.toString(k.getYearOfSales())+" "+k.getMonthOfSales(), k.getForecast());
        }
  
        
        monthlyTrends.addSeries(actual);  
        monthlyTrends.addSeries(forecast);  
       
       return monthlyTrends;
        
    }
//    public long getNewBaseProjection(){
//        System.out.println("new monthlyAdjustment" +current.getMonthlyGrowthAdjustment());
//        newBaseProjection = getFacade().calculateBaseProjection(current);
//        return newBaseProjection;
//    }
//    
//    public void setNewBaseProjection(long base){
//        
//        newBaseProjection = base;
//    }
//    
//    public long getNewForecastValue(){
//        System.out.println("current forecast" + current.getForecast());
//        newForecastValue = getFacade().calculateForecast(current);
//        return newForecastValue;
//        
//    }
//    
//    public void setNewForecastValue( long forecastValue){
//        newForecastValue = forecastValue;
//    }
//    
    
//    public SalesForecastEntity getBeforeUpdate(){
//        return beforeUpdate;
//    }
//    
//    public void setBeforeUpdate(SalesForecastEntity beforeUpdate){
//        this.beforeUpdate = beforeUpdate;
//    }
    
    public PieChartModel getPieModel(){
        pieModel = new PieChartModel(); 
        
        Collection<ProductPercentageQuantityEntity> ppqs = getSelected().getHistoricalPPQ();
        
        Iterator iterator = ppqs.iterator();
            while(iterator.hasNext()){
                
               ProductPercentageQuantityEntity element = (ProductPercentageQuantityEntity) iterator.next();
                pieModel.set(element.getProduct().getProductName(),element.getQuantity());
                        
            }
       
        
        return pieModel;
        
    }
    
     public SystemMessageController getSystemMessageController() {
        return systemMessageController;
    }

    public void setSystemMessageController(SystemMessageController systemMessageController) {
        this.systemMessageController = systemMessageController;
    }
    
    public void setPieModel(PieChartModel model){
        pieModel = model;
    }
  
    public SalesForecastEntity getSalesForecast(){
        return salesForecast;
    }
    
    public void setSalesForecast(SalesForecastEntity sales){
        salesForecast = sales;
    }
   

    public SalesForecastEntity getSelected() {
        if (current == null) {
            current = new SalesForecastEntity();
            selectedItemIndex = -1;
        }
        return current;
    }

    private SalesForecastEntityFacade getFacade() {
        return ejbFacade;
    }

    public PaginationHelper getPagination() {
        if (pagination == null) {
            pagination = new PaginationHelper(10) {

                @Override
                public int getItemsCount() {
                    return getFacade().count();
                }

                @Override
                public DataModel createPageDataModel() {
                    return new ListDataModel(getFacade().findRange(new int[]{getPageFirstItem(), getPageFirstItem() + getPageSize()}));
                }
            };
        }
        return pagination;
    }

    public String prepareList() {
        recreateModel();
        return "/entities/salesForecastEntity/List?faces-redirect=true";
    }

    public String prepareView() {
        current = (SalesForecastEntity) getItems().getRowData();
        selectedItemIndex = pagination.getPageFirstItem() + getItems().getRowIndex();
        return "View";
    }

    public String prepareCreate() {
        recreateModel();
        current = new SalesForecastEntity();
        selectedItemIndex = -1;
        return "/entities/salesForecastEntity/Create?faces-redirect=true";
    }

    public String create() {
        try {
            getFacade().create(current);
            JsfUtil.addSuccessMessage(ResourceBundle.getBundle("/Bundle").getString("SalesForecastEntityCreated"));
            return prepareCreate();
        } catch (Exception e) {
            JsfUtil.addErrorMessage(e, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
            return null;
        }
    }

    public String prepareEdit() {
        current = (SalesForecastEntity) getItems().getRowData();
        selectedItemIndex = pagination.getPageFirstItem() + getItems().getRowIndex();
        return "Edit";
    }
    
    public String change(SalesForecastEntity item){
        monthlyAdustBeforeUpdate = item.getMonthlyGrowthAdjustment();
        promotionBeforeUpdate =item.getExpectedMonthlyPromo();
        current = item;
        
        return "Edit";
    }
    
    public String analysis(SalesForecastEntity item){
        
        current = item;
        
        return "MonthlyAnalysis";
    }
    
    public String returnEdit(){
        
        
        current.setMonthlyGrowthAdjustment(monthlyAdustBeforeUpdate);
        current.setExpectedMonthlyPromo(promotionBeforeUpdate);
        return "/entities/salesForecastEntity/Edit?faces-redirect=true";
    }

    public String update() {
        try {
            updateYoYEntity(current);
            getFacade().edit(current);
//            System.out.println("lalala");
            MasterProductionScheduleMonthlyEntity mps = getFacade().findSameMonthMps(current);
            
//            System.out.println(mps.getId()+"MPSID");
            if(mps!=null){
                mps.setSafetyStock(calculateThisMonthOnHand(mps, monthlyFacade.getPreviousMonthOnHand(mps)));
                monthlyFacade.edit(mps);
                ArrayList<MasterProductionScheduleMonthlyEntity> monthlyMPS = new ArrayList<MasterProductionScheduleMonthlyEntity>();
                monthlyMPS = monthlyFacade.getAllMonthlyMPSFromMonthOnwards(mps);
                for (int i = 0; i < monthlyMPS.size(); i++) {
//                    System.out.println("inside hereeeeee"+monthlyMPS.get(i).getId());
                    if(monthlyMPS.get(i).getSalesForecast()!=null){
                    monthlyMPS.get(i).setSafetyStock(calculateThisMonthOnHand(monthlyMPS.get(i), monthlyFacade.getPreviousMonthOnHand(monthlyMPS.get(i))));
                    monthlyFacade.edit(monthlyMPS.get(i));
                    }
                }
            }
//            System.out.println("at the end");
            JsfUtil.addSuccessMessage(ResourceBundle.getBundle("/Bundle").getString("SalesForecastEntityUpdated"));
            DepartmentEntity productionDp = departmentFacade.findDepartmentByName(Department.ProductionPlanning.getName());
            SystemUserEntity productionManager = productionDp.getManager();
            String message = "Sales Forecast for Year " + current.getYearOfSales()+" ("+current.getExpectedYoYGrowth().getForecastPeriodType()+") "+current.getMonthOfSales()+" is updated"; 
               
        systemMessageController.getEjbFacade().createAndSendSystemMessage(productionManager,
                        message, "/entities/salesForecastEntity/List.xhtml", systemMessageController);
            return "/entities/salesForecastEntity/View?faces-redirect=true";
        } catch (Exception e) {
            JsfUtil.addErrorMessage(e, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
            return null;
        }
    }
    
    private long calculateThisMonthOnHand(MasterProductionScheduleMonthlyEntity mps, long previousMonth) {
        long thisMonthOnHand = 0;
        try{
        
        System.out.println(mps.getId()+"MPS ID IS HERE");
        thisMonthOnHand = mps.getFulfilledFigure() - mps.getSalesForecastFigure() + previousMonth;
        System.out.println("thismonth="+mps.getMonthOfProduction()+"previousmonth="+previousMonth+"thismonth="+thisMonthOnHand);
        
        return thisMonthOnHand;}
        catch(Exception e){e.printStackTrace();}
        return thisMonthOnHand;
    }

    public String destroy() {
        current = (SalesForecastEntity) getItems().getRowData();
        selectedItemIndex = pagination.getPageFirstItem() + getItems().getRowIndex();
        performDestroy();
        recreateModel();
        return "List";
    }

    public String destroyAndView() {
        performDestroy();
        recreateModel();
        updateCurrentItem();
        if (selectedItemIndex >= 0) {
            return "View";
        } else {
            // all items were removed - go back to list
            recreateModel();
            return "List";
        }
    }

    private void performDestroy() {
        try {
            getFacade().remove(current);
            JsfUtil.addSuccessMessage(ResourceBundle.getBundle("/Bundle").getString("SalesForecastEntityDeleted"));
        } catch (Exception e) {
            JsfUtil.addErrorMessage(e, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
        }
    }

    private void updateCurrentItem() {
        int count = getFacade().count();
        if (selectedItemIndex >= count) {
            // selected index cannot be bigger than number of items:
            selectedItemIndex = count - 1;
            // go to previous page if last page disappeared:
            if (pagination.getPageFirstItem() >= count) {
                pagination.previousPage();
            }
        }
        if (selectedItemIndex >= 0) {
            current = getFacade().findRange(new int[]{selectedItemIndex, selectedItemIndex + 1}).get(0);
        }
    }

    public DataModel getItems() {
        if (items == null) {
            items = getPagination().createPageDataModel();
        }
        return items;
    }
    
    public String updateForecast() {
        
        return "UpdateForecastView";
    }

    private void recreateModel() {
        items = null;
        current = null;
        
        
    }

    public String next() {
        getPagination().nextPage();
        recreateModel();
        return "List";
    }

    public String previous() {
        getPagination().previousPage();
        recreateModel();
        return "List";
    }

    public SelectItem[] getItemsAvailableSelectMany() {
        return JsfUtil.getSelectItems(ejbFacade.findAll(), false);
    }

    public SelectItem[] getItemsAvailableSelectOne() {
        return JsfUtil.getSelectItems(ejbFacade.findAll(), true);
    }

    public void updateYoYEntity(SalesForecastEntity currentItem) {
        ExpectedYearOnYearGrowthEntity yoy = currentItem.getExpectedYoYGrowth();
        Collection list = yoy.getSalesForecast();
        Iterator iterator = list.iterator();
        while(iterator.hasNext()){
            SalesForecastEntity sales = (SalesForecastEntity)iterator.next();
            System.out.println("salesId " + sales.getId());
            System.out.println("currentItemId "+ currentItem.getId());
            if(sales.getId()==currentItem.getId()){
               sales.setBaseProjection(currentItem.getBaseProjection());
               sales.setExpectedMonthlyPromo(currentItem.getExpectedMonthlyPromo());
               sales.setMonthlyGrowthAdjustment(currentItem.getMonthlyGrowthAdjustment());
               sales.setForecast(currentItem.getForecast());
                break;
            }
        }
        yoy.setSalesForecast(list);
        yoyFacade.edit(yoy);
        System.out.println("YOY updated");
        yoyFacade.flush();
    }
    
   public String cancelUpdate(){
       
       return "/entities/salesForecastEntity/List?faces-redirect=true";
   }

    

    @FacesConverter(forClass = SalesForecastEntity.class)
    public static class SalesForecastEntityControllerConverter implements Converter {

        public Object getAsObject(FacesContext facesContext, UIComponent component, String value) {
            if (value == null || value.length() == 0) {
                return null;
            }
            SalesForecastEntityController controller = (SalesForecastEntityController) facesContext.getApplication().getELResolver().
                    getValue(facesContext.getELContext(), null, "salesForecastEntityController");
            return controller.ejbFacade.find(getKey(value));
        }

        java.lang.Long getKey(String value) {
            java.lang.Long key;
            key = Long.valueOf(value);
            return key;
        }

        String getStringKey(java.lang.Long value) {
            StringBuffer sb = new StringBuffer();
            sb.append(value);
            return sb.toString();
        }

        public String getAsString(FacesContext facesContext, UIComponent component, Object object) {
            if (object == null) {
                return null;
            }
            if (object instanceof SalesForecastEntity) {
                SalesForecastEntity o = (SalesForecastEntity) object;
                return getStringKey(o.getId());
            } else {
                throw new IllegalArgumentException("object " + object + " is of type " + object.getClass().getName() + "; expected type: " + SalesForecastEntityController.class.getName());
            }
        }
    }
}

